
import java.sql.*;
import java.sql.Connection;
import java.util.*;
import javax.swing.JOptionPane;

public class Database {
  private
    Connection cnt;
    DataSet results;
    ResultSetMetaData rsmd;
    DatabaseMetaData dma;
    String[] types;
    String productName;
    String productVersion;

  /**
   * Constructeur
   * @param driver le nom du driver pour se connecter à la base postgreSQL
   */
  public Database(String driver) {
    try{
      types = new String[1];
      types[0] = "TABLE";
      Class.forName(driver);
    }
    catch (Exception ex){
      JOptionPane.showMessageDialog(null, "Erreur lors du chargement du driver :"+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
    }
  }

  /**
   * Connection à la base de donnée
   * @param url
   * @param username
   * @param password
   */
  public void open(String url, String username, String password) {
    try{
      cnt = DriverManager.getConnection(url, username, password);
      dma = cnt.getMetaData();
      productName = dma.getDatabaseProductName();
      productVersion = dma.getDatabaseProductVersion();
      results = new DataSet(dma.getCatalogs());
      String s[] = null;
      while(results.hasMoreElements()) {
        s = results.nextElement();
      }
    }
    catch (SQLException ex){
      JOptionPane.showMessageDialog(null, "Echec d'ouverture :"+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
    }
  }

  /**
   * Quitte la connection
   */
  public void close(){
    try{
      cnt.close();
    }
    catch (SQLException ex){
      JOptionPane.showMessageDialog(null, "Echec lors de la fermeture :"+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
    }
  }

  /**
   * 
   * @return
   */
  public String[] getTableNames() {
    String[] tbnames = null;
    Vector tname = new Vector();

    try{
      results = new DataSet(dma.getTables(null, null, "%", types));
      while (results.hasMoreElements())
        tname.addElement(results.getColumnValue("TABLE_NAME"));
    }
    catch (SQLException ex){
      JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
    }
    tbnames = new String[tname.size()];
    for(int i=0;i<tname.size();i++)
      tbnames[i] = (String)tname.elementAt(i);
    return tbnames;
  }

  /**
   * 
   * @return
   */
  public String[] getTableMetaData() {
    results = null;

    try{
      results = new DataSet(dma.getTables(null, null, "%", types));
    }
    catch (SQLException ex){
      JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
    }
    return results.getMetaData();
  }

  /**
   * 
   * @param tablename
   * @return
   */
  public String[] getColumnMetaData(String tablename) {
    results = null;

    try{
      results = new DataSet(dma.getColumns(null, null, tablename, null));
    }
    catch (SQLException ex){
      JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
    }
    return results.getMetaData();
  }

  /**
   * 
   * @param table
   * @return
   */
  public String[] getColumnNames(String table) {
    String[] tbnames = null;
    Vector tname = new Vector();

    try{
      results = new DataSet(dma.getTables(null, null, table, null));
      while (results.hasMoreElements())
        tname.addElement(results.getColumnValue("COLUMN_NAME"));
    }
    catch (SQLException ex){
      JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
    }
    tbnames = new String[tname.size()];
    for(int i=0;i<tname.size();i++)
      tbnames[i] = (String)tname.elementAt(i);
    return tbnames;
  }

  /**
   * 
   * @param table
   * @param columnName
   */
  public void getColumnValue(String table, String columnName) {
    try{
      if (table.length()>0)
        results = executeQuery("Select "+columnName+" from "+table+" order by "+columnName);
    }
    catch (Exception ex){
      JOptionPane.showMessageDialog(null, "Erreur sur la valeur de la colonne "+columnName+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
    }
  }

  /**
   * 
   * @param columnName
   * @return
   */
  public String getNextValue(String columnName) {
    String res = "";
    try{
      if (results.hasMoreElements())
        res = results.getColumnValue(columnName);
    }
    catch (Exception ex){
      JOptionPane.showMessageDialog(null, "Erreur sur la valeur suivante "+columnName+ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
    }
    return res;
  }

  /**
   * Exécute la requête
   * @param sql la requête à exécuter
   * @return
   */
  public DataSet executeQuery(String sql){
    results = null;
    try{
      Statement stmt = cnt.createStatement();
      results = new DataSet(stmt.executeQuery(sql));
    }
    catch (SQLException ex){
      JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
    }
    return results;
  }

  /**
   * 
   * @param sql
   */
  public void executeUpdate(String sql){
    try{
      Statement stmt = cnt.createStatement();
      stmt.executeUpdate(sql);
    }
    catch (SQLException ex){
      JOptionPane.showMessageDialog(null, ex.getMessage(), "Exception SQL", JOptionPane.ERROR_MESSAGE);
    }
  }

  /**
 * @return
 * @uml.property  name="productName"
 */
public String getProductName(){
    return productName;
  }

  /**
 * @return
 * @uml.property  name="productVersion"
 */
public String getProductVersion(){
    return productVersion;
  }
}


